/* 
Scenic Graphics Library
Copyright (C) 2007 Jouni Tulkki

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USApackage scenic;
*/

package scenic.toolkit.db;

import java.io.OutputStream;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

public class StorageOutputStreamImpl implements StorageOutputStream {
	private PrintStream os;
	private Map<Node, Long> objectMap = new HashMap<Node, Long>();
	private Vector<Node> objectVector = new Vector<Node>();
	private long objectIdCounter = 1;

	public StorageOutputStreamImpl(OutputStream os) {
		this.os = new PrintStream(os);
		objectVector.add(null);
	}
	
	private long getId(Node object) {
		if(object == null)
			return 0;
		Long value = objectMap.get(object);
		
		if(value == null) {
			long id = objectIdCounter++;

			objectVector.add(object);
			objectMap.put(object, new Long(id));
			return id;
		}
		return value.longValue();
	}

	public void writeRoot(Node object) {
		getId(object);
		
		for(int id = 1; id < objectVector.size(); id++)
			objectVector.elementAt(id).storeTo(this);
	}
	
	public void write(Record record) {
		os.println("@" + getId(record) + "=" + record.getType().getName());
		os.println("{");
		record.storeMembersTo(this);
		os.println("}");
	}
	
/*
	public void writeBooleanArray(BooleanArray array) {
		os.println("@" + getId(array) + "=boolean[] {");
		for(int i = 0; i < array.getLength(); i++) {
			if(i > 0)
				os.print(", ");
			os.print(array.get(i) ? "t" : "f");
		}
		os.println("}");		
	}
*/
	public void write(CharArray array) {
		os.println("@" + getId(array) + "=char[] \"" + array.toString() + "\"");
	}

	public void write(IntArray array) {
		os.print("@" + getId(array) + "=int[] {");
		for(int i = 0; i < array.getLength(); i++) {
			if(i > 0)
				os.print(", ");
			os.print(array.get(i));
		}
		os.println("}");		
	}

	public void write(DoubleArray array) {
		os.print("@" + getId(array) + "=double[] {");
		for(int i = 0; i < array.getLength(); i++) {
			if(i > 0)
				os.print(", ");
			os.print(array.get(i));
		}
		os.println("}");		
	}

	public void write(NodeArray array) {
		os.print("@" + getId(array) + "=" + array.getType().getElementType().getName() + "[] {");
		for(int i = 0; i < array.getLength(); i++) {
			if(i > 0)
				os.print(", ");
			os.print("@" + getId(array.get(i)));
		}
		os.println("}");		
	}
	
	public void writeMember(String name, boolean value) {
		os.println("\t" + name + "=" + (value ? "t" : "f"));
	}
	
	public void writeMember(String name, int value) {
		os.println("\t" + name + "=" + value);
	}

	public void writeMember(String name, double value) {
		os.println("\t" + name + "=" + value);
	}
	public void writeMember(String name, Node value) {
		os.println("\t" + name + "=@" + getId(value));
	}
}
